#ifndef _LOG_
#define _LOG_

#include <iostream>
#include <fstream>
#include <pthread.h>

#define WRITE_LOG_FILE 1
#define WRITE_TO_COUT 1
/*
	A logger that functions in a similar manner to an ostream, but isn't actually an ostream.
	Depending on the #defines above, the logger will right to multiple or no sources
*/
class Logger {

public:

	static Logger& getInstance();

	/* The output operation */
	template<typename T>
	Logger& operator<< (const T& output);

private:

	Logger();
	Logger(const Logger &);
	const Logger& operator= (const Logger &);
	~Logger();

	pthread_mutex_t lock;

#if WRITE_LOG_FILE
	std::ofstream fout;
#endif
};

//The global logger instance. Just say, "lout<<"Hello world!";"
extern Logger& lout;

//endl didn't want to work nicely, so I cheat and say this to make it work
#define endl '\n'


template<typename T>
Logger& Logger::operator<<(const T& t)
{
	pthread_mutex_lock(&lock);

#if WRITE_TO_COUT
	try {
		std::cout<<t;
		std::cout.flush();
	} catch(...) {}
#endif

#if WRITE_LOG_FILE
	fout<<t;
	fout.flush();
#endif

	pthread_mutex_unlock(&lock);

	return *this;
}


#endif // _LOG_

